package com.xsf.jieyou.business;


import com.xsf.jieyou.business.common.dto.ResponseResult;
import com.xsf.jieyou.business.common.dto.ResponseStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 全局业务异常处理
 *
 * @author xsfno1
 * @version v1.0.0
 * @date 2020/3/10
 **/
@Slf4j
@ControllerAdvice
public class BusinessExceptionHandler {
    /**
     * ExceptionHandler({BusinessException.class})
     * 如果是 Exception.class 那么出异常都不知道是哪里的BUG
     *
     * @return @{ResponseEntity}
     */
    @ExceptionHandler({BusinessException.class})
    public ResponseEntity<?> handlerException(HttpServletRequest request, Exception ex) {
        ResponseResult<?> error = new ResponseResult<>();
        // 自定义业务异常
        if (ex instanceof BusinessException) {
            error.setCode(((BusinessException) ex).getCode());
            error.setMessage(ex.getMessage());
        }
        // 请求类型错误
        else if (ex instanceof HttpRequestMethodNotSupportedException) {
            error.setCode(ResponseStatus.METHOD_NOT_ALLOWED.code());
            error.setMessage(ResponseStatus.METHOD_NOT_ALLOWED.message());
        }
        // 传输的参数错误
        else if (ex instanceof HttpMessageNotReadableException || ex instanceof NullPointerException) {
            error.setCode(ResponseStatus.REQUEST_PARAM_INVALID.code());
            error.setMessage(ResponseStatus.REQUEST_PARAM_INVALID.message());
        }
        // 错误请求
        else if (ex instanceof IllegalArgumentException) {
            error.setCode(ResponseStatus.ILLEGAL_REQUEST.code());
            error.setMessage(ResponseStatus.ILLEGAL_REQUEST.message());
        }
        // 无访问权限
        else if (ex instanceof AccessDeniedException) {
            error.setCode(ResponseStatus.INSUFFICIENT_AUTHORITY.code());
            error.setMessage(ResponseStatus.INSUFFICIENT_AUTHORITY.message());
        }
        // 无效令牌
        else if (ex instanceof InvalidTokenException) {
            error.setCode(ResponseStatus.INVALID_TOKEN.code());
            error.setMessage(ResponseStatus.INVALID_TOKEN.message());
        }
        // 请求超时
        else if (ex instanceof IOException) {
            error.setCode(ResponseStatus.REQUEST_TIMEOUT.code());
            error.setMessage(ResponseStatus.REQUEST_TIMEOUT.message());
        }
        // 未知错误
        else {
            error.setCode(ResponseStatus.UNKNOWN.code());
            error.setMessage(ResponseStatus.UNKNOWN.message());
        }
        log.warn("\n[全局业务异常]\r\n异常处理类：{}\r\n异常编码：{}\n异常消息：{}\r\n异常记录：{}",
                this.getClass().getName(), error.getCode(), error.getMessage(), ex.toString());
        return new ResponseEntity<>(error, HttpStatus.OK);
    }

}
